package com.broada.apm.model.performance;

import com.broada.apm.model.performance.IndicatorItem.Double;
import com.broada.apm.model.performance.IndicatorItem.Long;

public class IndicatorGroups {
	private final static String SPLIT_STR = "/";

	private final static String THROUGHPUT_TOTAL = SPLIT_STR + "throughput" + SPLIT_STR + "total";

	public abstract static class BaseGroups {
		protected String prefix;

		public BaseGroups(String prefix) {
			this.prefix = prefix;
		}

		public void update(String prefix, AbstractPerformance performance) {

		}

	}

	public static class Throughput extends BaseGroups {
		public final Long total = new Long(prefix + "throughput" + SPLIT_STR + "total", "总数");
		public final Long request = new Long(prefix + "request" + SPLIT_STR + "total", "请求次数");
//		public final Long response = new Long(prefix + "response", "应答次数");
		private final Double systemResponseRate = new Double(prefix + "response" + SPLIT_STR+ "rate", "响应率");

		public Throughput() {
			super("system" + SPLIT_STR);
		}
		
		public Throughput(String prefix) {
			super(prefix + SPLIT_STR);
		}

		public void update(String prefix, AbstractPerformance performance) {
//			total.set(performance, request.get(performance));
			long responseTotal = performance.getLong(prefix + SPLIT_STR  + "throughput" + SPLIT_STR + "total");
			long requestTotal = performance.getLong(prefix + SPLIT_STR  + "request" + SPLIT_STR + "total");
			if (responseTotal == 0 && requestTotal == 0) {
				// 均为0时，不计算响应率
			} else {
				systemResponseRate.set(performance, (responseTotal > requestTotal || requestTotal == 0) ? 100 : (long)((100 * responseTotal / requestTotal) * 100) / 100);
			}
		}
	}

	public static class UserGroup extends BaseGroups {
		public final Long unique = new Long(prefix + "unique", "独立用户数");
		public final Long unsatisfied = new Long(prefix + "unsatisfied", "不满意的用户数");

		public UserGroup() {
			super("system" + SPLIT_STR + "user" + SPLIT_STR);
		}
		
		public UserGroup(String prefix) {
			super(prefix + SPLIT_STR + "user" + SPLIT_STR);
		}
	}
	public static class ResponseTime extends BaseGroups{
	    public final Long total = new Long(prefix + "total", "响应时间总时长");
	    public final Long size = new Long(prefix + "size", "响应时间总个数");
		public final Long avg = new Long(prefix + "avg", "平均响应时间");
		public final Long min = new Long(prefix + "min", "最小响应时间");
		public final Long max = new Long(prefix + "max", "最大响应时间");
		public ResponseTime() {
			super("system" + SPLIT_STR + "response_time" + SPLIT_STR);
		}
		public ResponseTime(String prefix) {
			super(prefix + SPLIT_STR + "response_time" + SPLIT_STR);
		}
		@Override
		public void update(String prefix, AbstractPerformance performance) {
			if(size.get(performance) > 0)
				avg.set(performance, total.get(performance)/size.get(performance));
		}
	}

	public static class Apdex extends BaseGroups {
		private final Long apdex = new Long(prefix + "score" + SPLIT_STR + "apdex", "Apdex分数");
		private final Double successRate = new Double(prefix + "success" + SPLIT_STR+ "rate", "成功率");
		
		private final Long unsatisfied = new Long(prefix + "apdex" + SPLIT_STR + "unsatisfied", "不满意数");
		public final Long error = new Long(prefix+ "error" + SPLIT_STR + "count", "l7层错误数");
		public final Long satisfied = new Long(prefix + "apdex" + SPLIT_STR + "satisfied", "满意数");
		public final Long tolerate = new Long(prefix + "apdex" + SPLIT_STR + "tolerate", "容忍数");

		public Apdex() {
			super("system" + SPLIT_STR);
		}
		
		public Apdex(String prefix) {
			super(prefix + SPLIT_STR);
		}

		@Override
		public void update(String prefix, AbstractPerformance performance) {
			long output = performance.getLong(prefix + THROUGHPUT_TOTAL);
			if (output > 0) {
				unsatisfied.set(performance, output - satisfied.get(performance) - tolerate.get(performance));
				apdex.set(performance,
						(long) (100 * (satisfied.get(performance) + tolerate.get(performance) * 0.5) / output));
				successRate.set(performance, (long)((100.00 - 100.00 * error.get(performance) / output) * 100) / 100.00);
				if (performance.getDouble(prefix + SPLIT_STR + "response" + SPLIT_STR+ "rate") < performance.getDouble(prefix + SPLIT_STR + "success" + SPLIT_STR+ "rate")) {
					Double systemResponseRate = new Double(prefix + SPLIT_STR + "response" + SPLIT_STR + "rate", "响应率");
					systemResponseRate.set(performance, performance.getDouble(prefix + SPLIT_STR + "success" + SPLIT_STR+ "rate"));
				}
			} else {
				long outputRequest = performance.getLong(prefix + THROUGHPUT_TOTAL);
				if(outputRequest > 0) {
					successRate.set(performance, 100.00);
					if (performance.getDouble(prefix + SPLIT_STR + "response" + SPLIT_STR+ "rate") < performance.getDouble(prefix + SPLIT_STR + "success" + SPLIT_STR+ "rate")) {
						Double systemResponseRate = new Double(prefix + SPLIT_STR + "response" + SPLIT_STR+ "rate", "响应率");
						systemResponseRate.set(performance, 100.00);
					}
				}
			}
		}
	}
}
